<template>
	<view class="u-collapse-item" :style="[itemStyle]">
		<view :hover-stay-time="200" class="u-collapse-head" @click.stop="headClick" :hover-class="hoverClass" :style="[headStyle]">
			<block v-if="!$slots['title-all']">
				<view v-if="!$slots['title']" class="u-collapse-title u-line-1" :style="[{ textAlign: align ? align : 'left' }, isShow && activeStyle && !arrow ? activeStyle : '']">
					{{ title }}
				</view>
				<slot v-else name="title" />
				<view class="u-icon-wrap">
					<u-icon v-if="arrow" :color="arrowColor" :class="{ 'u-arrow-down-icon-active': isShow }" class="u-arrow-down-icon" name="arrow-down"></u-icon>
				</view>
			</block>
			<slot v-else name="title-all" />
		</view>
		<view
			class="u-collapse-body"
			:style="[
				{
					height: isShow ? height + 'px' : '0'
				}
			]"
		>
			<view class="u-collapse-content" :id="elId" :style="[bodyStyle]"><slot></slot></view>
		</view>
	</view>
</template>

<script>
/**
 * collapseItem 手风琴Item
 * @description 通过折叠面板收纳内容区域（搭配u-collapse使用）
 * @tutorial https://www.uviewui.com/components/collapse.html
 * @property {String} title 面板标题
 * @property {String Number} index 主要用于事件的回调，标识那个Item被点击
 * @property {Boolean} disabled 面板是否可以打开或收起（默认false）
 * @property {Boolean} open 设置某个面板的初始状态是否打开（默认false）
 * @property {String Number} name 唯一标识符，如不设置，默认用当前collapse-item的索引值
 * @property {String} align 标题的对齐方式（默认left）
 * @property {Object} active-style 不显示箭头时，可以添加当前选择的collapse-item活动样式，对象形式
 * @event {Function} change 某个item被打开或者收起时触发
 * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
 */
export default {
	name: 'u-collapse-item',
	emits: ['change'],
	props: {
		// 标题
		title: {
			type: String,
			default: ''
		},
		// 标题的对齐方式
		align: {
			type: String,
			default: 'left'
		},
		// 是否可以点击收起
		disabled: {
			type: Boolean,
			default: false
		},
		// collapse显示与否
		open: {
			type: Boolean,
			default: false
		},
		// 唯一标识符
		name: {
			type: [Number, String],
			default: ''
		},
		//活动样式
		activeStyle: {
			type: Object,
			default() {
				return {};
			}
		},
		// 标识当前为第几个
		index: {
			type: [String, Number],
			default: ''
		}
	},
	data() {
		return {
			isShow: false,
			elId: this.$u.guid(),
			height: 0, // body内容的高度
			headStyle: {}, // 头部样式，对象形式
			bodyStyle: {}, // 主体部分样式
			itemStyle: {}, // 每个item的整体样式
			arrowColor: '', // 箭头的颜色
			hoverClass: '', // 头部按下时的效果样式类
			arrow: true // 是否显示右侧箭头
		};
	},
	watch: {
		open(val) {
			this.isShow = val;
		}
	},
	created() {
		this.parent = false;
		// 获取u-collapse的信息，放在u-collapse是为了方便，不用每个u-collapse-item写一遍
		this.isShow = this.open;
	},
	methods: {
		// 异步获取内容，或者动态修改了内容时，需要重新初始化
		init() {
			this.parent = this.$u.$parent.call(this, 'u-collapse');
			if (this.parent) {
				this.nameSync = this.name ? this.name : this.parent.childrens.length;
				this.parent.childrens.push(this);
				this.headStyle = this.parent.headStyle;
				this.bodyStyle = this.parent.bodyStyle;
				this.arrowColor = this.parent.arrowColor;
				this.hoverClass = this.parent.hoverClass;
				this.arrow = this.parent.arrow;
				this.itemStyle = this.parent.itemStyle;
			}
			this.$nextTick(() => {
				this.queryRect();
			});
		},
		// 点击collapsehead头部
		headClick() {
			if (this.disabled) return;
			if (this.parent && this.parent.accordion == true) {
				this.parent.childrens.map((val) => {
					// 自身不设置为false，因为后面有this.isShow = !this.isShow;处理了
					if (this != val) {
						val.isShow = false;
					}
				});
			}

			this.isShow = !this.isShow;
			// 触发本组件的事件
			this.$emit('change', {
				index: this.index,
				show: this.isShow
			});
			// 只有在打开时才发出事件
			if (this.isShow) this.parent && this.parent.onChange();
			// this.$forceUpdate();
		},
		// 查询内容高度
		queryRect() {
			// $uGetRect为uView自带的节点查询简化方法，详见文档介绍：https://www.uviewui.com/js/getRect.html
			// 组件内部一般用this.$uGetRect，对外的为this.$u.getRect，二者功能一致，名称不同
			this.$uGetRect('#' + this.elId).then((res) => {
				this.height = res.height;
			});
		}
	},
	mounted() {
		this.init();
	}
};
</script>

<style lang="scss" scoped>
@import '../../libs/css/style.components.scss';

.u-collapse-head {
	position: relative;
	@include vue-flex;
	justify-content: space-between;
	align-items: center;
	color: #3396fb;
	font-size: 17px;
	line-height: 48rpx;
	font-weight: bold;
	padding: 26rpx;
	text-align: left;
	box-shadow: 0 1rpx 0 0 rgba(226, 226, 226, 0.5);
	background-color: #fff;
}

.u-collapse-item {
	overflow: hidden;
	border-radius: 12rpx;
	border-bottom: 20rpx solid #f5f7fa;
}

.u-collapse-title {
	flex: 1;
	overflow: hidden;
}

.u-arrow-down-icon {
	transition: all 0.3s;
	margin-right: 20rpx;
	margin-left: 14rpx;
}

.u-arrow-down-icon-active {
	transform: rotate(180deg);
	transform-origin: center center;
}

.u-collapse-body {
	overflow: hidden;
	transition: all 0.3s;
}

.u-collapse-content {
	overflow: hidden;
	font-size: 28rpx;
	color: $u-tips-color;
	text-align: left;
}
</style>
